<?php

class CommonParser
{
	protected $warnings = array();
	protected $errors = array();
	protected $blocks;				//esto almacena BlockParsers con clave id
	protected $parameters;			//esto guarda pares nombre=>default value
	protected $content;				//el contenido literal, debe rellenarse en los constructores de las subclases
	public $debug = 2;
	
	
	protected function warn($str)
	{
		$this->warnings[] = $str;
		if($this->debug>1) echo "Warning: $str\n";
	}
	
	protected function err($str)
	{
		$this->errors[] = $str;
		if($this->debug>1) echo "Error. $str\n";
	}
	
	//Esto reemplaza el contenido de los tags block con una llamada a su clase->render()
	protected function replaceBlocks()
	{
		//esto es optimizable, haciendo que en el parse se marque a qué content-area pertenece cada bloque
		//$xp = new DOMXpath($this->dom);
		foreach($this->blocks as $id=>$parser)
		{
			$cur_xml = get_node_content($content, "Block", $id);
			$this->content = str_replace($cur_xml, "<?php echo \$this->blocks[\"$id\"]->render(); ?>", $content);
		}
	}
	
	
	//esta función recibe un xml crudo (se usa el $content), y procesa el primer <mvf:Parameters que encuentra
	protected function parseParameters()
	{	
		if(func_num_args()==0) $src = $this->content;
		else $src = func_get_arg(0);
		
		if($this->debug>1) echo "CommonParser:parse().   content mide ".strlen($this->content)."\n";
		$xml_parameters = get_node_content($src, "Parameters");
		$rex = "/\\<mvf\:Parameter\\b.*?\\bname\\=\"([a-zA-Z]\\w*?)\".*?(?:\\bvalue=\"(.*?)\")*.*?\\/\\>/s";
		preg_match_all($rex, $xml_parameters, $matches);
		for($i=0; $i<sizeof($matches[1]); $i++)
		{
			$this->parameters[$matches[1][$i]] = $matches[2][$i];
		}	
		if($this->debug>1) echo "CommonParser:parse() OK.   content mide ".strlen($this->content)."\n";	
	}
	
	
	//Esto localiza los blocks que hay en un nodo (el $content), y crea un parser para cada uno
	protected function parseBlocks()
	{	
		if($this->debug>1) echo "CommonParser:parseBlocks().   content mide ".strlen($this->content)."\n";
		
		$this->blocks = array();
		if(func_num_args()==0) $xml = $this->content;
		else $xml = func_get_arg(0);
		
		do
		{
			$cur_xml = get_node_content($xml, "Block");
			if($this->debug>1) echo "Bloque del mal con ".strlen($cur_xml)." caracters\n";
			if(strlen($cur_xml)==0) break;
			
			$attr = get_node_attributes($cur_xml, "Block", array("id", "type", "codefile"));
			$id = $attr["id"];
			$type = $attr["type"];
			$codefile = $attr["codefile"];
			
			$parser = new BlockParser();
			//si tiene codefile, es external
			//si dice que es external, y no tiene codefile, casco
			if($type=="external") $parser->loadFile($codefile);
			else $parser->loadContent($cur_xml);
			$parser->parse();			
			$this->blocks[$id] = $parser;
			
			$xml = str_replace($cur_xml, "", $xml);
		} 
		while(true);	
		
		if($this->debug>1) echo "CommonParser:parseBlocks() OK.   content mide ".strlen($this->content)."\n";	
	}
}

?>